package com.jcx.ldzj.service.impl;

import com.baomidou.mybatisplus.extension.api.R;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.jcx.ldzj.config.UserConfig;
import com.jcx.ldzj.dao.SysMenuMapper;
import com.jcx.ldzj.emun.MyCode;
import com.jcx.ldzj.emun.SystemCode;
import com.jcx.ldzj.entity.LoginUser;
import com.jcx.ldzj.entity.RoleMenuRelation;
import com.jcx.ldzj.entity.SysMenu;
import com.jcx.ldzj.entity.UserRoleRelation;
import com.jcx.ldzj.service.IRoleMenuRelationService;
import com.jcx.ldzj.service.ISysMenuService;
import com.jcx.ldzj.service.IUserInfoService;
import com.jcx.ldzj.service.IUserRoleRelationService;
import com.jcx.ldzj.utile.RedisUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.shiro.SecurityUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.stream.Collectors;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author ld
 * @since 2021-06-25
 */
@Slf4j
@Service
public class SysMenuServiceImpl extends ServiceImpl<SysMenuMapper, SysMenu> implements ISysMenuService {
    @Autowired
    private IRoleMenuRelationService iRoleMenuRelationService;
    @Autowired
    private IUserRoleRelationService iUserRoleRelationService;
    @Autowired
    private IUserInfoService iUserInfoService;

    @Autowired
    private RedisUtil redisclient;

    @Autowired
    private UserConfig userConfig;

    @Override
    public R<List<SysMenu>> getMenuTree() {
        LoginUser login = (LoginUser) SecurityUtils.getSubject().getPrincipal();
        if(login==null){
            return R.failed(MyCode.用户未登录_请确认登录后再试);
        }
        if(login.isAdmin()){
            return R.ok(this.getTree(new ArrayList<>(),this.baseMapper.selectToMenu(), 0l));
        }
        return R.ok(this.getMenuTreeByAuth(login.getUserName()));
    }

    public List<SysMenu> getMenuTreeByAuth(String userName) {
        //获取该用户具有的权限菜单关系，用于菜单显示过滤
        List<String> menu = redisclient.lRange(SystemCode.USER_ROLES_PERMISSIONS + userName, 0, -1);
        List<SysMenu> list = this.baseMapper.selectToMenu();
        Iterator<SysMenu> it = list.iterator();
        while (it.hasNext()){
            SysMenu sysMenu = it.next();
            if(!menu.contains(sysMenu.getMenuId().toString())){
                it.remove();
            }
        }
        return this.getTree(new ArrayList<>(),list, 0l);
    }



    @Override
    public List<SysMenu> getMenuTreeAll() {
        List<SysMenu> list = this.getTree(new ArrayList<>(),this.list(), 0l);
          return list;
    }
    /**
     * 构建菜单树
     * @param list
     * @param parentId
     * @return
     */
    private List<SysMenu> getTree(List<SysMenu> list,List<SysMenu> sysMenus,Long parentId){
        List<SysMenu> collect = sysMenus.stream().filter(sysMenu -> parentId.equals(sysMenu.getParentId())).collect(Collectors.toList());
        for (int i = 0; i <collect.size() ; i++) {
            SysMenu sysMenu = collect.get(i);
            List<SysMenu> tree = this.getTree(new ArrayList<SysMenu>(),sysMenus, sysMenu.getMenuId());
            if(tree!=null&&tree.size()>0){
                sysMenu.setChrilds(tree);
            }
            list.add(sysMenu);
        }
        return list;
    }

    @Override
    public boolean saveMenu(SysMenu sysMenu) {
        int i = this.baseMapper.insert(sysMenu);
        if(i>0){
            return true;
        }
        return false;
    }

    @Override
    public boolean updateMenuById(SysMenu sysMenu) {
        //被修改的菜单可能已经存在缓存了，所以需要重写加载
        this.cleanRedisMenu(sysMenu.getMenuId().toString());
        int i = this.baseMapper.updateById(sysMenu);
        if(i>0){
            return true;
        }
        return false;
    }

    /**
     * 重置菜单对应的用户的缓存信息
     * @param menuId
     */
    public void cleanRedisMenu(String menuId){
        List<RoleMenuRelation> rolesBymenuId = iRoleMenuRelationService.getRolesBymenuId(menuId);
        Set<String>  set=new HashSet();
        for (int i = 0; i < rolesBymenuId.size(); i++) {
            RoleMenuRelation roleMenuRelation = rolesBymenuId.get(i);
            List<UserRoleRelation> list = iUserRoleRelationService.getByroleId(roleMenuRelation.getRoleId());
            List<String> collect = list.stream().map(UserRoleRelation::getUserId).collect(Collectors.toList());
            set.addAll(collect);
        }
        Iterator<String> it = set.iterator();
        while (it.hasNext()) {
            String str = it.next();
            userConfig.setRoles(iUserInfoService.getById(str));
        }
    }


}
